#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "debugcmd.h"

int i2c_read_handler(void *cmd, char *param)
{
    uint32_t slave;
    uint32_t reg;

    sscanf(param, "0x%x 0x%x", &slave, &reg);

    printf("i2c read cmd is running\r\n");
    printf("slave = 0x%02x\r\n", slave);
    printf("reg   = 0x%02x\r\n", reg);

    return 0;
}

int i2c_write_handler(void *cmd, char *param)
{
    uint32_t slave;
    uint32_t reg;
    uint32_t val;

    sscanf(param, "0x%x 0x%x 0x%x", &slave, &reg, &val);

    printf("i2c write cmd is running\r\n");
    printf("slave = 0x%02x\r\n", slave);
    printf("reg   = 0x%02x\r\n", reg);
    printf("val   = 0x%02x\r\n", val);

    return 0;
}

int i2c_dump_handler(void *cmd, char *param)
{
    uint32_t slave;

    sscanf(param, "0x%x", &slave);

    printf("i2c dump cmd is running\r\n");
    printf("slave = 0x%02x\r\n", slave);

    return 0;
}

int sys_exit_handler(void *cmd, char *param)
{
    printf("exit.\r\n");
    exit(0);
    return 0;
}

DEBUGCMD_MCMD i2c           = {"i2c",       "i2c bus debug command."};
DEBUGCMD_SCMD i2c_read      = {"read",      "i2c read <slave> <reg>.",          i2c_read_handler};
DEBUGCMD_SCMD i2c_write     = {"write",     "i2c wrtie <slave> <reg> <val>.",   i2c_write_handler};
DEBUGCMD_SCMD i2c_dump      = {"dump",      "i2c dump <slave>.",                i2c_dump_handler};
DEBUGCMD_MCMD spi           = {"spi",       "spi bus debug command."};
DEBUGCMD_MCMD sys           = {"sys",       "system debug command"};
DEBUGCMD_SCMD sys_exit      = {"exit",      "system exit.",                     sys_exit_handler};

int main()
{
    char cmd[DEBUGCMD_MAX_STR_LEN];
    char c;
    debugcmd_init();

    debugcmd_mcmd_register(&i2c);
    debugcmd_scmd_register(&i2c, &i2c_read);
    debugcmd_scmd_register(&i2c, &i2c_write);
    debugcmd_scmd_register(&i2c, &i2c_dump);
    debugcmd_mcmd_register(&spi);
    debugcmd_mcmd_register(&sys);
    debugcmd_scmd_register(&sys, &sys_exit);

    debugcmd_scmd_unregister(&i2c_read);
    debugcmd_scmd_unregister(&i2c_write);
    debugcmd_scmd_unregister(&i2c_dump);
    debugcmd_mcmd_unregister(&i2c);
    debugcmd_mcmd_unregister(&spi);
    debugcmd_scmd_unregister(&sys_exit);
    debugcmd_mcmd_unregister(&sys);

    debugcmd_mcmd_register(&i2c);
    debugcmd_scmd_register(&i2c, &i2c_read);
    debugcmd_scmd_register(&i2c, &i2c_write);
    debugcmd_scmd_register(&i2c, &i2c_dump);
    debugcmd_mcmd_register(&spi);
    debugcmd_mcmd_register(&sys);
    debugcmd_scmd_register(&sys, &sys_exit);

#if 0
    /* 完整的测试用例 */
    printf("==================================================\r\n");
    printf("?\r\n");
    printf("----------------\r\n");
    debugcmd_execute("?");                     // OK
    printf("==================================================\r\n");
    printf(" ?\r\n");
    printf("----------------\r\n");
    debugcmd_execute(" ?");                    // OK
    printf("==================================================\r\n");
    printf("  ?   \r\n");
    printf("----------------\r\n");
    debugcmd_execute("  ?   ");                // OK
    printf("==================================================\r\n");
    printf("? xxx\r\n");
    printf("----------------\r\n");
    debugcmd_execute("? xxx");                 // ---> NG, 应该报错
    printf("==================================================\r\n");
    printf("xxx\r\n");
    printf("----------------\r\n");
    debugcmd_execute("xxx");                   // OK
    printf("==================================================\r\n");
    printf("xxx xxx\r\n");
    printf("----------------\r\n");
    debugcmd_execute("xxx xxx");               // OK
    printf("==================================================\r\n");
    printf("i2c\r\n");
    printf("----------------\r\n");
    debugcmd_execute("i2c");                   // OK
    printf("==================================================\r\n");
    printf("i2c ?\r\n");
    printf("----------------\r\n");
    debugcmd_execute("i2c ?");                 // OK
    printf("==================================================\r\n");
    printf("i2c read 0x48 0x1A\r\n");
    printf("----------------\r\n");
    debugcmd_execute("i2c read 0x48 0x1A");    // OK
    printf("==================================================\r\n");
    printf("i2c xxx\r\n");
    printf("----------------\r\n");
    debugcmd_execute("i2c xxx");               // OK
    printf("==================================================\r\n");
    printf("i2c xxx xxx\r\n");
    printf("----------------\r\n");
    debugcmd_execute("i2c xxx xxx");           // OK
    printf("==================================================\r\n");
    printf("i2c read 0x48 0x1A\r\n");
    printf("----------------\r\n");
    debugcmd_execute("i2c read 0x48 0x1A");    // OK
    printf("==================================================\r\n");
    printf("i2c write 0x48 0x1A 0x03\r\n");
    printf("----------------\r\n");
    debugcmd_execute("i2c write 0x48 0x1A 0x03");  // OK
    printf("==================================================\r\n");
    printf("i2c dump 0x48\r\n");
    printf("----------------\r\n");
    debugcmd_execute("i2c dump 0x48");             // OK
    printf("==================================================\r\n");
#endif

    while(1)
    {
        printf(">>> ");
        fflush(stdin);                              // 接收前清空缓冲区
        scanf("%[^\n]", cmd);                       // 以换行符作为字符串输入的结束, 不接收换行符
        scanf("%c", &c);                            // 用一个单独的char接收换行符

        // printf("cmd = \"%s\"\r\n", cmd);
        // printf("c = 0x%02x\r\n", c);

        if((cmd[0] == '\0') && (c == 0x0a))
        {
            // printf("continue\r\n");
            continue;
        }

        debugcmd_execute(cmd);
        memset(cmd, 0, DEBUGCMD_MAX_STR_LEN);
    }

    return 0;
}

